package demo.ftpclient;

import java.io.FileInputStream;
import java.io.FileOutputStream;

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;

import android.util.Log;

public class FtpClient
{
  private static final String TAG = "FtpClient";
  
  private FTPClient mFTPClient = null;

  public static boolean ftpDowload( String host, String username, String password, String srcFilePath, String desFilePath, int port )
  {
    FtpClient fc = new FtpClient();
    if( !fc.ftpConnect( host, username, password, port ) )
      return false;
    boolean success = fc.ftpDownload( srcFilePath, desFilePath );
    fc.ftpDisconnect();
    return success;
  }
  public boolean ftpConnect( String host, String username, String password )
  {
    return ftpConnect( host, username, password, 21 );
  }
  
  public boolean ftpConnect( String host, String username, String password, int port )
  {
    try
    {
      mFTPClient = new FTPClient();
      // connecting to the host
      mFTPClient.connect( host, port );

      // now check the reply code, if positive mean connection success
      if ( FTPReply.isPositiveCompletion( mFTPClient.getReplyCode() ) )
      {
        // login using username & password
        boolean status = mFTPClient.login( username, password );

        /*
         * Set File Transfer Mode
         * 
         * To avoid corruption issue you must specified a correct transfer mode, such as ASCII_FILE_TYPE,
         * BINARY_FILE_TYPE, EBCDIC_FILE_TYPE .etc. Here, I use BINARY_FILE_TYPE for transferring text, image, and
         * compressed files.
         */
        mFTPClient.setFileType( FTP.BINARY_FILE_TYPE );
        mFTPClient.enterLocalPassiveMode();

        return status;
      }
    }
    catch ( Exception e )
    {
      Log.e(TAG, "Error: could not connect to host " + host + ": " + e.getMessage() );
    }

    return false;
  }

  public boolean ftpDisconnect()
  {
    try
    {
      mFTPClient.logout();
      mFTPClient.disconnect();
      return true;
    }
    catch ( Exception e )
    {
      Log.e( TAG, "Error occurred while disconnecting from ftp server: " + e.getMessage() );
    }

    return false;
  }

  public String ftpGetCurrentWorkingDirectory()
  {
    try
    {
      String workingDir = mFTPClient.printWorkingDirectory();
      return workingDir;
    }
    catch ( Exception e )
    {
      Log.e( TAG, "Error: could not get current working directory: " + e.getMessage() );
    }

    return null;
  }

  public boolean ftpChangeDirectory( String directory_path )
  {
    try
    {
      mFTPClient.changeWorkingDirectory( directory_path );
    }
    catch ( Exception e )
    {
      Log.e( TAG, "Error: could not change directory to " + directory_path + ": " + e.getMessage() );
    }

    return false;
  }

  public void ftpPrintFilesList( String dir_path )
  {
    try
    {
      FTPFile[] ftpFiles = mFTPClient.listFiles( dir_path );
      int length = ftpFiles.length;

      for ( int i = 0; i < length; i++ )
      {
        String name = ftpFiles[i].getName();
        boolean isFile = ftpFiles[i].isFile();

        if ( isFile )
        {
          Log.i( TAG, "File : " + name );
        }
        else
        {
          Log.i( TAG, "Directory : " + name );
        }
      }
    }
    catch ( Exception e )
    {
      e.printStackTrace();
    }
  }

  public boolean ftpMakeDirectory( String new_dir_path )
  {
    try
    {
      boolean status = mFTPClient.makeDirectory( new_dir_path );
      return status;
    }
    catch ( Exception e )
    {
      Log.e( TAG, "Error: could not create new directory named " + new_dir_path + ": " + e.getMessage() );
    }

    return false;
  }

  public boolean ftpRemoveDirectory( String dir_path )
  {
    try
    {
      boolean status = mFTPClient.removeDirectory( dir_path );
      return status;
    }
    catch ( Exception e )
    {
      Log.e( TAG, "Error: could not remove directory named " + dir_path + ": " + e.getMessage() );
    }

    return false;
  }

  public boolean ftpRemoveFile( String filePath )
  {
    try
    {
      boolean status = mFTPClient.deleteFile( filePath );
      return status;
    }
    catch ( Exception e )
    {
      e.printStackTrace();
    }

    return false;
  }

  public boolean ftpRenameFile( String from, String to )
  {
    try
    {
      boolean status = mFTPClient.rename( from, to );
      return status;
    }
    catch ( Exception e )
    {
      Log.e( TAG, "Could not rename file: " + from + " to: " + to + ": " + e.getMessage() );
    }

    return false;
  }

  /**
   * mFTPClient: FTP client connection object (see FTP connection example) 
   * srcFilePath: path to the source file in FTP server 
   * desFilePath: path to the destination file to be saved in sdcard
   */
  public boolean ftpDownload( String srcFilePath, String desFilePath )
  {
    boolean status = false;
    try
    {
      FileOutputStream desFileStream = new FileOutputStream( desFilePath );
      status = mFTPClient.retrieveFile( srcFilePath, desFileStream );
      desFileStream.flush();
      desFileStream.close();

      return status;
    }
    catch ( Exception e )
    {
      Log.e(TAG, "download failed: " + e.getMessage() );
    }

    return status;
  }

  /**
   * mFTPClient: FTP client connection object (see FTP connection example) srcFilePath: source file path in sdcard
   * desFileName: file name to be stored in FTP server desDirectory: directory path where the file should be upload to
   */
  public boolean ftpUpload( String srcFilePath, String desFileName, String desDirectory )
  {
    boolean status = false;
    try
    {
      FileInputStream srcFileStream = new FileInputStream( srcFilePath );

      // change working directory to the destination directory
      if ( ftpChangeDirectory( desDirectory ) )
      {
        status = mFTPClient.storeFile( desFileName, srcFileStream );
      }

      srcFileStream.close();
      return status;
    }
    catch ( Exception e )
    {
      Log.e( TAG, "upload failed: " + e.getMessage() );
    }

    return status;
  }
}
